/* 
 * This file is part of Last.fm Now Playing Plugi-in for Adium
 * Copyright (c) 2011 Anton Bronnikov <anton.bronnikov@gmail.com>.
 * 
 * Last.fm Now Playing Plugi-in for Adium is free software: you can redistribute
 * it and/or modify it under the terms of the GNU General Public License as 
 * published by the Free Software Foundation, either version 3 of the License, 
 * or (at * your option) any later version.
 * 
 * Last.fm Now Playing Plugi-in for Adium is distributed in the hope that it 
 * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty 
 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General 
 * Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along with 
 * Last.fm Now Playing Plugi-in for Adium. If not, see 
 * <http://www.gnu.org/licenses/>.
 *
 */

#import "LastFmNowPlayingPreferences.h"
#import <Adium/AISharedAdium.h>
#import <Adium/AIPreferenceControllerProtocol.h>
#import <Adium/ESDebugAILog.h>

NSString * const PREFERENCE_PANE_NAME           = @"Last.fm";
NSString * const PREFERENCE_GROUP_LASTFM        = @"lastFmNowPlayingPlugin";
NSString * const PREFERENCE_KEY_LASTFMUSERID    = @"lastFmUserID";
NSString * const PREFERENCE_KEY_PLUGINISENABLED = @"pluginIsEnabled";

NSString * const PREFERENCE_STRING_YES   = @"YES";
NSString * const PREFERENCE_STRING_NO    = @"NO";
NSString * const PREFERENCE_STRING_EMPTY = @"";

NSString * const WARNING_USERNOTVALIDATED     = @"Warning: it was not possible to validate user ID \'%@\'.  Please make sure you use the correct one.";

NSInteger const CHECKBOX_STATE_ON  = 1;
NSInteger const CHECKBOX_STATE_OFF = 0;

#pragma mark -
#pragma mark Private interface : LastFmPreferences

@interface LastFmNowPlayingPreferences(private) 

#pragma mark -
#pragma mark Methods

- (void) alignValidationWarning;

@end

#pragma mark -
#pragma mark Implementation : LastFmPreferences

static LastFmNowPlayingPreferences * sharedInstance = nil;

@implementation LastFmNowPlayingPreferences

#pragma mark -
#pragma mark Synthesized properties

@synthesize delegate = _delegate;

#pragma mark -
#pragma mark Property : lastFmUserID

- (NSString *) lastFmUserID {
  if (!_lastFmUserID) {
    // Get the first value from preferences
    _lastFmUserID = [[adium.preferenceController preferenceForKey:PREFERENCE_KEY_LASTFMUSERID                      
                                                            group:PREFERENCE_GROUP_LASTFM] copy];
    
    // Use empty string in case if there were none
    if (!_lastFmUserID) {
      _lastFmUserID = PREFERENCE_STRING_EMPTY;
    }
  }
  
  AILogWithSignature(@"lastFmUserID == \'%@\'", _lastFmUserID);

  return _lastFmUserID;
}

- (void) setLastFmUserID:(NSString *)newLastFmUserID {
  // Replace nil with empty string
  if (!newLastFmUserID) {
    newLastFmUserID = PREFERENCE_STRING_EMPTY;
  }

  // If the new value is the same as old one do nothing
  if ([self.lastFmUserID isEqualToString:newLastFmUserID]) {
    return;
  }
  
  // Copy the value
  [_lastFmUserID release];
  _lastFmUserID = [newLastFmUserID copy];
  
  // Store new value in preferences
  [adium.preferenceController setPreference:_lastFmUserID
                                     forKey:PREFERENCE_KEY_LASTFMUSERID 
                                      group:PREFERENCE_GROUP_LASTFM];

  AILogWithSignature(@"lastFmUserID = \'%@\'", _lastFmUserID);

  // Notify the delegate (if any) on change
  NSObject <LastFmNowPlayingPreferencesDelegate> * tempDelegate = self.delegate;
  
  if (tempDelegate && [tempDelegate respondsToSelector:@selector(changedLastFmUserID:)]) {
    [tempDelegate changedLastFmUserID:self];
  }
}

#pragma mark -
#pragma mark Property : pluginIsEnabled

- (BOOL) pluginIsEnabled {
  if (!_pluginIsEnabledWasInitialised) {
    // Get string value of the preference
    NSString * stringPluginIsEnabled = [adium.preferenceController preferenceForKey:PREFERENCE_KEY_PLUGINISENABLED                      
                                                                              group:PREFERENCE_GROUP_LASTFM];
    
    // Use empty string if it's not yet assigned
    if (!stringPluginIsEnabled) {
      stringPluginIsEnabled = PREFERENCE_STRING_EMPTY;
    }
    
    // Compare it against the YES-constant
    _pluginIsEnabled = [stringPluginIsEnabled isEqualToString:PREFERENCE_STRING_YES];
    
    _pluginIsEnabledWasInitialised = YES;
  }

  AILogWithSignature(@"pluginIsEnabled == %i", _pluginIsEnabled);

  return _pluginIsEnabled;
}

- (void) setPluginIsEnabled:(BOOL)newPluginIsEnabled {
  // If the new value is the same as old one do nothing
  if ((self.pluginIsEnabled && newPluginIsEnabled) || (!self.pluginIsEnabled && !newPluginIsEnabled)) {
    return;
  }
  
  // Create string representation of a BOOL value
  NSString * stringPluginIsEnabled = newPluginIsEnabled ? PREFERENCE_STRING_YES : PREFERENCE_STRING_NO;
  
  // Store new value in preferences & save it internally
  [adium.preferenceController setPreference:stringPluginIsEnabled
                                     forKey:PREFERENCE_KEY_PLUGINISENABLED 
                                      group:PREFERENCE_GROUP_LASTFM];
  _pluginIsEnabled = newPluginIsEnabled;
  
  AILogWithSignature(@"pluginIsEnabled = %i (%@)", newPluginIsEnabled, stringPluginIsEnabled);
  
  // Notify the delegate (if any) on change
  NSObject <LastFmNowPlayingPreferencesDelegate> * tempDelegate = self.delegate;
  
  if (tempDelegate && [tempDelegate respondsToSelector:@selector(changedPluginIsEnabled:)]) {
    [tempDelegate changedPluginIsEnabled:self];
  }  
}

#pragma mark -
#pragma mark User interface

- (void) alignValidationWarning {
  AILogWithSignature(@"Checking if user ID validation warning should be displayed");
  
  // Don't show warning if there is no user ID
  if ([self.lastFmUserID isEqualToString:PREFERENCE_STRING_EMPTY]) {
    [fieldLastFmUserIDValidationWarning setHidden:YES];
    return;
  }
  
  // Don't show warning if there is no delegate to validate a user ID with
  if (!self.delegate || ![self.delegate respondsToSelector:@selector(validateLastFmUserID:)]) {
    [fieldLastFmUserIDValidationWarning setHidden:YES];
    return;
  }    
    
  // Don't show warning if the user ID is validated  
  if ([self.delegate validateLastFmUserID:self.lastFmUserID]) {
    [fieldLastFmUserIDValidationWarning setHidden:YES];
    return;
  }
  
  // Now really show it
  fieldLastFmUserIDValidationWarning.stringValue = [NSString stringWithFormat:WARNING_USERNOTVALIDATED, self.lastFmUserID];
  [fieldLastFmUserIDValidationWarning setHidden:NO];
}

- (IBAction)checkBoxWasUpdated:(id)sender {
  AILogWithSignature(@"Check-box was changed %@", sender);
  
  if (sender == buttonPluginIsEnabled) {
    self.pluginIsEnabled = ([buttonPluginIsEnabled state] == CHECKBOX_STATE_ON ? YES : NO);
  }
}

#pragma mark -
#pragma mark Protocol : NSTextFieldDelegate

- (BOOL)control:(NSControl *)control textShouldEndEditing:(NSText *)fieldEditor {
  AILogWithSignature(@"Text field is going to change: %@", control);
    
  if (control == fieldLastFmUserID) {
    self.lastFmUserID = fieldLastFmUserID.stringValue;
    [self alignValidationWarning];
  }
  
  return YES;
}

#pragma mark -
#pragma mark Adium integration

- (void)viewDidLoad {
  AILogWithSignature(@"Loading preferences pane");
  
  fieldLastFmUserID.stringValue = self.lastFmUserID;
  [buttonPluginIsEnabled setState:(self.pluginIsEnabled ? CHECKBOX_STATE_ON : CHECKBOX_STATE_OFF)];
  
  [self alignValidationWarning];
  
  [super viewDidLoad];
}

- (void)viewWillClose {
  AILogWithSignature(@"Unloading preferences pane");
  
  [super viewWillClose];
}

#pragma mark -

- (AIPreferenceCategory)category {
  return AIPref_Advanced;
}

- (NSString *)label {
  return PREFERENCE_PANE_NAME;
}

- (NSString *)nibName {
  return @"LastFmNowPlayingPreferences";
}

- (NSImage *)image {
  return [[[NSImage alloc] initWithContentsOfFile:[[NSBundle bundleForClass:[self class]] pathForImageResource:@"lastfm"]] autorelease];
}

- (BOOL)resizable {
  return YES;
}

- (BOOL)resizableHorizontally {
  return YES;
}

#pragma mark -
#pragma mark Shared instance

+ (LastFmNowPlayingPreferences *)sharedInstance {
  AILogWithSignature(@"Get shared instance of LastFmPreferences");
  
  @synchronized([LastFmNowPlayingPreferences class]) {
    if (!sharedInstance) {
      sharedInstance = [[LastFmNowPlayingPreferences alloc] init];
    }
  }
  
  return sharedInstance;
}

#pragma mark -
#pragma mark Object life-cycle

- (id) init {
  self = [super init];
  
  if (self) {
    _delegate = nil;
    _lastFmUserID = nil;
    _pluginIsEnabledWasInitialised = NO;
  }
    
  return self;
}

- (void) dealloc {
  // User interface
  if (fieldLastFmUserID) { 
    [fieldLastFmUserID release];
    fieldLastFmUserID = nil;
  }
  
  if (fieldLastFmUserIDValidationWarning) {
    [fieldLastFmUserIDValidationWarning release];
    fieldLastFmUserIDValidationWarning = nil;
  }
  
  if (buttonPluginIsEnabled) { 
    [buttonPluginIsEnabled release];
    buttonPluginIsEnabled = nil;
  }
  
  // Instance variables
  if (_delegate) {
    _delegate = nil;
  }
  
  if (_lastFmUserID) { 
    [_lastFmUserID release];
    _lastFmUserID = nil;
  }
  
  [super dealloc];
}

@end
